package llmserviceopenai.model

import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.json.JsonElement


@Serializable
data class ChatCompletionResponse(
    val id: String,
    val `object`: String = "chat.completion",        // 使用 `object`（反引号包裹）
    val created: Long = System.currentTimeMillis() / 1000,
    val model: String,
    val choices: List<Choice>,
    val usage: Usage? = null
)

@Serializable
data class ChatMessage(
    val role: String,
    val content: String,
    val name: String? = null
)

@Serializable
data class Function(
    val name: String,
    val description: String? = null,
    val parameters: JsonElement
)

@Serializable
data class Tool(
    val type: String, // 目前主要是 "function"
    val function: Function
)

@Serializable
data class ChatCompletionRequest(
    val model: String,
    val messages: List<ChatMessage>,

    @SerialName("max_tokens")
    val maxToken: Int? = 502,
    val temperature: Double? = 0.7,

    @SerialName("top_p")
    val topP: Double? = 1.0,
    val stream: Boolean? = false,
    val user: String? = null,
    val stop: String? = null,
    val tools: List<Tool>? = null,

    @SerialName("tool_choice")
    val toolsChoice: ToolChoice? = null,

    /**
     * 重复惩罚机制，防止模型重复生成相同内容。
     * >1.0 减少重复，<1.0 增加重复。
     * 典型值：1.0 ~ 2.0
     */
    @SerialName("frequency_penalty")
    val frequencyPenalty: Double? = null,

    /**
     * 主题惩罚机制，鼓励模型探索新主题。
     * >0.0 更倾向于新话题。
     */
    @SerialName("presence_penalty")
    val persencePenalty: Double? = null,

    /**
     * 种子值，用于实现确定性输出（如果支持）
     * 设置后，相同输入和种子将产生一致结果
     */
    val seed: Int? = null,

    // 针对有think开关的模型，例如qwen
    @SerialName("extra_body")
    val extraBody: Map<String, JsonElement>? = null,

    // 针对qwen think开关
    @SerialName("chat_template_kwargs")
    val chatTemplateKwargs: Map<String, Boolean?>? = null
)


@Serializable
sealed interface ToolChoice


@Serializable
data class ToolChoiceObject(
    val type: String,
    val function: NamedFunction
) : ToolChoice


@Serializable
data class NamedFunction(
    val name: String
) : ToolChoice


@Serializable
data class Choice(
    val index: Int,
    val message: ChatMessage,
    @SerialName("finish_reason")
    val finishReason: String? = null
)

@Serializable
data class Usage(
    @SerialName("prompt_tokens")
    val promptTokens: Int,
    @SerialName("completion_tokens")
    val completionTokens: Int,
    @SerialName("total_tokens")
    val totalTokens: Int
)


@Serializable
data class ChatCompletionChunk(
    val id: String,
    val `object`: String,
    val created: Long,
    val model: String,
    val choices: List<ChunkChoice>
) {
    @Serializable
    data class ChunkChoice(
        val index: Int,
        val delta: DeltaMessage,
        val logprobs: JsonElement? = null,
        @SerialName("finish_reason")
        val finishReason: String? = null
    )

    @Serializable
    data class DeltaMessage(
        val role: String? = null,
        val content: String? = null
    )
}
